﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Ninject;
using XHouse.Data.Interfaces;
using XHouse.Model;

namespace XHouse.Data
{
    public class Repository<T> : IRepository<T> where T : Identity
    {
        private readonly DbContext db;
        private readonly IDbSet<T> dbset;

        /// <summary>
        /// Initialises a new instance of the Repository class.
        /// </summary>
        /// <param name="dbFactory">A valid DatabaseFactory <see cref="XHouse.Data.DatabaseFactory"/> object.</param>
        [Inject]
        public Repository(IDatabaseFactory dbFactory)
        {
            if (dbFactory == null)
                throw new ArgumentNullException("dbFactory");

            db = dbFactory.Get();
            dbset = db.Set<T>();
        }

        public T Get(int id)
        {
            T model = dbset.Find(id);
            return model;
        }

        public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
        {
            return dbset.Where(predicate).AsEnumerable();
        }

        public IEnumerable<T> GetAll()
        {
            return dbset.AsEnumerable();
        }

        public IQueryable<T> GetQueryable(int id)
        {
            return GetQueryable(m => m.Id == id);
        }

        public IQueryable<T> GetQueryable(Expression<Func<T, bool>> predicate)
        {
            return dbset.Where(predicate);
        }

        public T Add(T model)
        {
            dbset.Add(model);
            //Save();

            return model;
        }

        public T Update(T model)
        {
            //db.Entry(model).State = EntityState.Modified;
            T modelaux = dbset.Find(model.Id);
            db.Entry(modelaux).CurrentValues.SetValues(model);
            //Save();

            return model;
        }

        public void Remove(int id)
        {
            var model = dbset.Find(id);
            Remove(model);
        }

        public void Remove(T model)
        {
            if (model == null)
                return;

            db.Entry(model).State = EntityState.Deleted;
            //Save();
        }

        public void Save()
        {
            db.SaveChanges();
        }

        public void Dispose()
        {
            //db.Dispose();
        }
    }
}
